package cz.ctu.guiproject.client.networking.listener;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

import cz.ctu.guiproject.client.networking.ClientNetworkAgentImpl;

/**
 * This class listens to the events from the server. It is aimed to be used with
 * the ClientNetworkAgent only.
 * 
 * @author tomas.buk
 */
public class ServerListenerImpl implements ServerListener {

	// default output stream used to send messages to server
	private ObjectInputStream input;
	// client for notification, that particular event occured
	private ClientNetworkAgentImpl client;
	// flag used to indicate, that this thread instance is running
	private boolean running;
	// flag used to terminate connection without reconnection attempt
	private boolean forceDisconnect;
	private static final Logger logger = Logger.getLogger(ServerListenerImpl.class.getName());

	/**
	 * Default ServerListener constructor, called from the ClientNetworkAgent
	 * 
	 * @param client
	 *            Particular instance of the ClientNetworkAgent
	 * @param socket
	 *            Socket, used to handle connection with server
	 */
	public ServerListenerImpl(ClientNetworkAgentImpl client, Socket socket) {
		this.client = client;
		running = false;
		try {
			this.input = new ObjectInputStream(socket.getInputStream());
			running = true;
		} catch (IOException ex) {
			logger.log(Level.SEVERE, ex.getMessage());
			client.connectionFailed(true);
		}
	}

	/**
	 * Sets the running flag with the appropriate value.
	 * 
	 * @param running
	 *            New flag value
	 */
	public void setRunning(boolean running) {
		this.running = running;
	}

	@Override
	public void disconnect() {
		try {
			if (input != null) {
				input.close();
			}
		} catch (IOException ex) {
			logger.log(Level.WARNING, "ServerListener disconnected: " + ex.getMessage());
		}
	}

	@Override
	public void run() {
		while (running) {
			try {
				Object msg = input.readObject();
				client.messageReceived(msg);

			} catch (IOException ex) {
				// TODO prepsat do podoby .properties souboru
				logger.log(Level.SEVERE, "Server closed the connection: " + ex.getMessage());
				running = false;
			} catch (ClassNotFoundException ex) {
				logger.log(Level.SEVERE, "Error occured during type conversion: " + ex.getMessage());
			}
		}
//		// set this flag according to disconnect request!!!
//		if (!forceDisconnect) {
//			// try to reconnect
//			client.connectionFailed(false);
//		}
		client.connectionFailed(!forceDisconnect);
	}

	public void disableReconnect() {
		forceDisconnect = true;
	}
}
